﻿using System;
using System.Web;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Web.Script.Serialization;
using System.Text.RegularExpressions;

namespace WebHttpApi.WebHttpApi.Core
{
    /// <summary>
    /// WebSdkCore 的摘要说明：公共类
    /// </summary>
    public class WebSdkCore
    {
        //<summary>共用函数㈠：CRC相关</summary>
        #region  CRC16
        public static byte[] CRC16(byte[] data)
        {
            int len = data.Length;
            if (len > 0)
            {
                ushort crc = 0xFFFF;

                for (int i = 0; i < len; i++)
                {
                    crc = (ushort)(crc ^ (data[i]));
                    for (int j = 0; j < 8; j++)
                    {
                        crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1);
                    }
                }
                byte hi = (byte)((crc & 0xFF00) >> 8);  //高位置
                byte lo = (byte)(crc & 0x00FF);         //低位置

                return new byte[] { hi, lo };
            }
            return new byte[] { 0, 0 };
        }
        #endregion

        #region  ToCRC16
        public static string ToCRC16(string content)
        {
            return ToCRC16(content, Encoding.UTF8);
        }

        public static string ToCRC16(string content, bool isReverse)
        {
            return ToCRC16(content, Encoding.UTF8, isReverse);
        }

        public static string ToCRC16(string content, Encoding encoding)
        {
            return ByteToString(CRC16(encoding.GetBytes(content)), true);
        }

        public static string ToCRC16(string content, Encoding encoding, bool isReverse)
        {
            return ByteToString(CRC16(encoding.GetBytes(content)), isReverse);
        }

        public static string ToCRC16(byte[] data)
        {
            return ByteToString(CRC16(data), true);
        }

        public static string ToCRC16(byte[] data, bool isReverse)
        {
            return ByteToString(CRC16(data), isReverse);
        }
        #endregion

        #region  ToModbusCRC16
        public static string ToModbusCRC16(string s)
        {
            return ToModbusCRC16(s, true);
        }

        public static string ToModbusCRC16(string s, bool isReverse)
        {
            return ByteToString(CRC16(StringToHexByte(s)), isReverse);
        }

        public static string ToModbusCRC16(byte[] data)
        {
            return ToModbusCRC16(data, true);
        }

        public static string ToModbusCRC16(byte[] data, bool isReverse)
        {
            return ByteToString(CRC16(data), isReverse);
        }
        #endregion

        #region  ByteToString
        public static string ByteToString(byte[] arr, bool isReverse)
        {
            try
            {
                byte hi = arr[0], lo = arr[1];
                return Convert.ToString(isReverse ? hi + lo * 0x100 : hi * 0x100 + lo, 16).ToUpper().PadLeft(4, '0');
            }
            catch (Exception ex) { throw (ex); }
        }

        public static string ByteToString(byte[] arr)
        {
            try
            {
                return ByteToString(arr, true);
            }
            catch (Exception ex) { throw (ex); }
        }
        #endregion

        #region  StringToHexString
        public static string StringToHexString(string str)
        {
            StringBuilder s = new StringBuilder();
            foreach (short c in str.ToCharArray())
            {
                s.Append(c.ToString("X4"));
            }
            return s.ToString();
        }
        #endregion

        #region  StringToHexByte
        private static string ConvertChinese(string str)
        {
            StringBuilder s = new StringBuilder();
            foreach (short c in str.ToCharArray())
            {
                if (c <= 0 || c >= 127)
                {
                    s.Append(c.ToString("X4"));
                }
                else
                {
                    s.Append((char)c);
                }
            }
            return s.ToString();
        }

        private static string FilterChinese(string str)
        {
            StringBuilder s = new StringBuilder();
            foreach (short c in str.ToCharArray())
            {
                if (c > 0 && c < 127)
                {
                    s.Append((char)c);
                }
            }
            return s.ToString();
        }

        // 字符串转16进制字符数组
        // <param name="hex"></param>
        public static byte[] StringToHexByte(string str)
        {
            return StringToHexByte(str, false);
        }

        // 字符串转16进制字符数组
        // <param name="str"></param>
        // <param name="isFilterChinese">是否过滤掉中文字符</param>
        public static byte[] StringToHexByte(string str, bool isFilterChinese)
        {
            string hex = isFilterChinese ? FilterChinese(str) : ConvertChinese(str);

            //清除所有空格
            hex = hex.Replace(" ", "");
            //若字符个数为奇数，补一个0
            hex += hex.Length % 2 != 0 ? "0" : "";

            byte[] result = new byte[hex.Length / 2];
            for (int i = 0, c = result.Length; i < c; i++)
            {
                result[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
            }
            return result;
        }
        #endregion
        //<summary共用函数㈠：>CRC相关</summary>

        //<summary>共用函数㈡：JSON相关</summary>
        #region JSONs
        public static string ToJSON(object obj)
        {
            StringBuilder sb = new StringBuilder();
            JavaScriptSerializer json = new JavaScriptSerializer();
            json.Serialize(obj, sb);
            return sb.ToString();
        }
        #endregion
        //<summary>共用函数㈡：JSON相关</summary>

        //<summary>共用函数㈢：MD5相关</summary>
        #region MD5加密
        // 通过字符串获取MD5值，返回32位字符串。
        public static string GetMD5String(string text)
        {
            MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(text));
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }
            return sBuilder.ToString().ToLower();
        }

        public static string MD5_32(string str)
        {
            byte[] b = System.Text.Encoding.Default.GetBytes(str);
            b = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(b);

            string ret = "";
            for (int i = 0; i < b.Length; i++)
            {
                ret += b[i].ToString("x").PadLeft(2, '0');
            }
            return ret;
        }

        public static string GetMD5(string myString)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] fromData = System.Text.Encoding.UTF8.GetBytes(myString);
            byte[] targetData = md5.ComputeHash(fromData);
            string byte2String = null;

            for (int i = 0; i < targetData.Length; i++)
            {
                byte2String += targetData[i].ToString("x2");
            }

            return byte2String;
        }
        #endregion
        //<summary>共用函数㈢：MD5相关</summary>

        //<summary>共用函数㈣：数据库相关</summary>
        #region 数据库操作
        //MSSQL数据库查询
        public static System.Data.DataTable select(string sql)
        {
            string connstring = System.Configuration.ConfigurationManager.ConnectionStrings["strCon"].ToString();

            SqlConnection conn = new SqlConnection(connstring);

            SqlCommand cmd = new SqlCommand(sql, conn);
            SqlDataAdapter sda = new SqlDataAdapter(cmd);
            System.Data.DataTable dt = new System.Data.DataTable();

            try
            {
                conn.Open();
                sda.Fill(dt);
            }
            catch
            {
            }

            conn.Close();
            cmd.Dispose();
            return dt;
        }

        //MSSQL 增改删
        public static bool insert_update_delete(string sql)
        {
            bool result = false;

            string connstring = System.Configuration.ConfigurationManager.ConnectionStrings["strCon"].ToString();

            SqlConnection conn = new SqlConnection(connstring);

            SqlCommand cmd = new SqlCommand(sql, conn);

            try
            {
                conn.Open();
                cmd.ExecuteNonQuery();
                result = true;
            }
            catch
            {
                result = false;
            }

            conn.Close();
            cmd.Dispose();

            return result;
        }
        #endregion
        //<summary>共用函数㈣：数据库相关</summary>

        //<summary>共用函数㈤：获取时间戳</summary>
        public static string GetTimeStamp()
        {
            TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }
        //<summary>共用函数㈤：获取时间戳</summary>

        //<summary>共用函数㈥：CS校验和计算</summary>
        public static string CS(string str_cs)
        {
            string string_cs = "";
            int dec = 0;
            int sum = 0;

            for (int i = 0; i < str_cs.Length / 2; i++)
            {
                dec = Convert.ToInt32(str_cs.Substring(i * 2, 2), 16);
                sum = sum + dec;
            }

            string_cs = Convert.ToString(sum, 16);
            string_cs = "00" + string_cs;
            string_cs = string_cs.Substring(string_cs.Length - 2);

            return string_cs;
        }
        //<summary>共用函数㈥：CS校验和计算</summary>
        /// <summary>
        /// 倒序排列
        /// </summary>
        /// <param name="str">传入的数据</param>
        /// <returns></returns>
        public static string Reverse_order(string str)
        {
            string[] array = Regex.Split(str, "(?<=\\G.{2})").Where(f => !string.IsNullOrEmpty(f)).ToArray();
            array = array.Reverse().ToArray();
            string result = string.Join("", array);
            return result;


        }
    }
}